package com.topvision.opencv_test;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;

import com.google.zxing.Result;
import com.topvision.opencv_test.SampleApplication.RecoActivity;

import org.opencv.android.Utils;
import org.opencv.core.Mat;

import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends Activity implements Camera.PreviewCallback {
    static {
        System.loadLibrary("opencv_java");
    }

    private static final String TAG = "MainActivity";
    private SurfaceView picSV;
    private Camera camera;
    private String strPicPath;
    private DrawRectHandler mDrawRectHandler;
    private DrawRectView mDrawRectView;
    private ImageView mImageView;
    public int zoomIndex;
    public int indexCount;
    private boolean isQRcode;

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        picSV = (SurfaceView) findViewById(R.id.picSV);
        mDrawRectView = (DrawRectView) findViewById(R.id.drawRectView);
        mImageView = (ImageView) findViewById(R.id.iv);
        picSV.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        picSV.getHolder().addCallback(new MyCallback());
        mDrawRectHandler = new DrawRectHandler(mDrawRectView, this);
        //提交到GIT
    }

    private class MyCallback implements Callback {
        //我们在SurfaceView创建的时候就要进行打开摄像头、设置预览取景所在的SurfaceView、设置拍照的参数、开启预览取景等操作
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            try {
                camera = Camera.open();//打开摄像头
                camera.setPreviewDisplay(picSV.getHolder());//设置picSV来进行预览取景
                camera.setPreviewCallback(MainActivity.this);
                Camera.Parameters params = camera.getParameters();//获取照相机的参数
                params.setPictureSize(1920, 1080);//设置照片的大小为1920*1080
                params.setPreviewSize(1920, 1080);//设置预览取景的大小为1920*1080
//                params.setFlashMode("auto");//开启闪光灯
//                params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
//                params.setJpegQuality(100);
                camera.setParameters(params);
                camera.startPreview();
                LightSensorManager.getInstance().start(MainActivity.this);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            //当SurfaceView销毁时，我们进行停止预览、释放摄像机、垃圾回收等工作
            releaseResouce();
        }
    }

    public void takepic(View v) {
        //在我们开始拍照前，实现自动对焦
        camera.autoFocus(new MyAutoFocusCallback());
    }

    private void releaseResouce() {
        if (camera != null) {
            camera.setPreviewCallback(null);
            camera.stopPreview();
            camera.release();
            camera = null;
        }
        LightSensorManager.getInstance().stop();
    }

    private class MyAutoFocusCallback implements AutoFocusCallback {
        @Override
        public void onAutoFocus(boolean success, Camera camera) {
            //开始拍照
            camera.takePicture(null, null, null, new MyPictureCallback());
        }
    }

    private class MyPictureCallback implements PictureCallback {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            try {
                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                Matrix matrix = new Matrix();
                matrix.preRotate(90);
                bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
                        bitmap.getHeight(), matrix, true);
                strPicPath =
                        Environment.getExternalStorageDirectory() + "/1Zxing/" + System.currentTimeMillis() + ".jpg";
                FileOutputStream fos = new FileOutputStream(strPicPath);
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
                fos.close();
                Handler mHandler = new Handler();
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
//                        Other.ttt2(strPicPath);
                    }
                });
                camera.startPreview();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public boolean onTouchEvent(MotionEvent event) {
        int Action = event.getAction();
        if (MotionEvent.ACTION_UP == Action) {
            camera.autoFocus(new AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {

                }
            });
        }
        return true;
    }

    @Override
    public void onPreviewFrame(final byte[] data, Camera camera) {
        //光线太暗不检测
        if (LightSensorManager.getInstance().getLux() < 300) det21D(data);
        else indexCount = 0;
    }

    private void det21D(byte[] data) {
        //TODO 算法只能在单一背景上效果优秀，有杂物的时候效果差（待优化解决）
//        ResultBean resultBean = FindQRCodeUtils.findQRCode(camera, data);
        ResultBean resultBean = Other.ttt2(camera, data);
        if (resultBean != null) {
            mDrawRectHandler.sendMessage(Message.obtain(mDrawRectHandler, 0, resultBean.mRect));
            decodeImage(resultBean.mResultImage, resultBean.mSrcImage);
        }
    }

    protected void decodeImage(final Mat resultImage, final Mat srcImage) {
        if (resultImage.size().width == 0 || resultImage.size().height == 0) return;
        new Thread(new Runnable() {
            @Override
            public void run() {
                final Bitmap bitmap = Bitmap.createBitmap(resultImage.width(), resultImage.height(), Bitmap.Config.RGB_565);
                Utils.matToBitmap(resultImage, bitmap);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (srcImage != null)
                            mImageView.setImageBitmap(bitmap);
                    }
                });
                final Result result = QRCodeDecoder.syncDecodeQRCode(bitmap);
                if (result == null) {
                    if (srcImage != null) {
                        decodeImage(srcImage, null);
                    } else {
                        /* 走到这里说明这一次的识别没有识别到二维码 */
                        //这里需要计数（大约100次左右未识别到，然后就调换到Vuforia去识别图片）
                        if (!isQRcode && indexCount++ == 25) {
                            releaseResouce();
                            if (camera == null) {
                                startActivity(new Intent(MainActivity.this, RecoActivity.class).addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION));
                                finish();
                            }
                        }
                        isQRcode = false;
                        System.out.println("indexCount: " + indexCount);
                    }
                } else {
                    /* 到这里说明已经识别到是个二维码 */
                    if (result.getText().length() == 13) {
                        System.out.println("识别到可能是13位条形码:" + result.getText());
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                ToastUtils.showToast(MainActivity.this, "识别到可能是13位条形码:" + result.getText());
                            }
                        });
                    } else {
                        System.out.println("识别到:" + result.getText());
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                ToastUtils.showToast(MainActivity.this, "识别到:" + result.getText());
                            }
                        });
                    }
                    isQRcode = true;
                    indexCount = 0;
//                    zoomIndex = 0;
                }
            }
        }).start();
    }

    /**
     * 设置相机变焦
     */
    private Camera.Parameters p;

    public void setZoom(int value) {
        if (camera == null) return;
        p = camera.getParameters();
        if (Build.BRAND.equalsIgnoreCase("topsmart") || Build.BRAND.equalsIgnoreCase("toptrue")) {
            int maxZoomLevel = p.getMaxZoom() / 2;
            if (value < maxZoomLevel) {
                p.setZoom(value);
            } else {
                p.setZoom(maxZoomLevel);
            }
            camera.setParameters(p);
        } else {
            if (p.isZoomSupported() && p.isSmoothZoomSupported()) {
                int maxZoomLevel = p.getMaxZoom() / 2;
                if (value < maxZoomLevel) {
                    camera.startSmoothZoom(value);
                } else {
                    camera.startSmoothZoom(maxZoomLevel);
                }
            }
        }
        if (p.isZoomSupported() && p.isSmoothZoomSupported()) {
            int maxZoomLevel = p.getMaxZoom() / 2;
            if (value < maxZoomLevel) {
                if (Build.BRAND.equalsIgnoreCase("topsmart") || Build.BRAND.equalsIgnoreCase("toptrue")) {

                }
                camera.startSmoothZoom(value);
            } else {
                camera.startSmoothZoom(maxZoomLevel);
            }
        } else if (p.isZoomSupported() && !p.isSmoothZoomSupported()) {
            int maxZoomLevel = p.getMaxZoom() / 2;
            if (value < maxZoomLevel) {
                p.setZoom(value);
            } else {
                p.setZoom(maxZoomLevel);
            }
            camera.setParameters(p);
        }
    }
}
